using MicroMsg.Common.Event;
using MicroMsg.Common.Timer;
using MicroMsg.Common.Utils;
using MicroMsg.Scene;
using Microsoft.Phone.Notification;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Text;
using System.Threading;
using System.Windows;
namespace MicroMsg.Manager
{
	public class PushNotifyMgr
	{
		private const string TAG = "PushNotify";
		private const string old_channelNameHead = "MicroMsgPushChannel";
		private const string channelNameHead = "MMPC";
		public const string nSwitchPushNotifyKey = "nSwitchPushNotify";
		private const int PUSH_DEFAULT = 1;
		private string mChannelName;
		private HttpNotificationChannel mPushChannel;
		private EventWatcher mAuthWatcher;
		private TimerObject mTimerObject;
		private bool isOpenChannelFromSync;
		public bool gotChannelUrl;
		public bool regCompleted;
		public AutoResetEvent waitPushEvent = new AutoResetEvent(false);
		public PushNotifyMgr()
		{
			Log.smethod_4("PushNotify", "push channel init, device id = " + Util.getDeviceUniqueId());
			this.mAuthWatcher = new EventWatcher(this, null, new EventHandlerDelegate(this.onWatcherHandler));
			EventCenter.registerEventWatcher(EventConst.ON_NETSCENE_AUTH_SUCCESS, this.mAuthWatcher);
			EventCenter.registerEventWatcher(EventConst.ON_NET_LONGCONN_KEEPALIVE, this.mAuthWatcher);
			if (!AccountMgr.hasValidAccount())
			{
				PushNotifyMgr.cleanPushSetting();
			}
			this.checkOpenPushChannel();
			this.checkNeedRegisterChannel();
			Log.smethod_4("PushNotify", "push channel init over. ");
		}
		public void setEnable(bool enable)
		{
			if (!enable)
			{
				this.setEnable(PushNotifySwitch.PushDisable);
				return;
			}
			this.setEnable(PushNotifySwitch.PushEnable);
		}
		public bool getEnable()
		{
			return this.isAccountEnablePush();
		}
		public void openPushChannelForExit()
		{
			if (!AccountMgr.hasValidAccount())
			{
				Log.smethod_1("PushNotify", "openPushChannelForExit failed without valid account. ");
				return;
			}
			this.setEnable(true);
			if (this.mTimerObject != null)
			{
				this.mTimerObject.stop();
			}
			this.mTimerObject = TimerService.addTimer(10, new EventHandler(this.onOpenPushchannelTimeout));
			this.mTimerObject.start();
		}
		public void resetOpenPushChannelTimeout()
		{
			if (this.mTimerObject != null)
			{
				this.mTimerObject.stop();
				this.mTimerObject = null;
			}
		}
		public void onOpenPushchannelTimeout(object sender, EventArgs e)
		{
			this.resetOpenPushChannelTimeout();
			EventCenter.postEvent(EventConst.ON_NETSCENE_PUSHCHANNEL_REG_OVER, false, null);
		}
		public bool openPushSync()
		{
			if (!AccountMgr.hasValidAccount())
			{
				Log.smethod_1("PushNotify", "cannot open(sync) channel without valid account. ");
				return false;
			}
			if (ConfigMgr.getInt("nSwitchPushNotify", 1) == 0 && this.mPushChannel != null && this.getCurrentConnStatus() == null)
			{
				Log.smethod_4("PushNotify", "openPushSync is ignored,  channel open already. ");
				return true;
			}
			Log.smethod_4("PushNotify", "openPushSync... start.... ");
			ConfigMgr.setInt("nSwitchPushNotify", 0);
			this.doClosePushChannel();
			this.isOpenChannelFromSync = true;
			this.regCompleted = false;
			this.gotChannelUrl = false;
			this.checkOpenPushChannel();
			this.checkNeedRegisterChannel();
			if (this.regCompleted && this.gotChannelUrl)
			{
				Log.smethod_4("PushNotify", "openPushSync... success. ");
				return true;
			}
			this.waitPushEvent.WaitOne(10000);
			if (this.regCompleted && this.gotChannelUrl)
			{
				Log.smethod_4("PushNotify", "openPushSync... success. ");
				return true;
			}
			Log.smethod_4("PushNotify", "openPushSync... failed! ");
			return false;
		}
		public void setEnable(PushNotifySwitch enable)
		{
			if (!AccountMgr.hasValidAccount())
			{
				Log.smethod_1("PushNotify", "cannot set enable without valid account. ");
				return;
			}
			if (enable == (PushNotifySwitch)ConfigMgr.getInt("nSwitchPushNotify", 1))
			{
				Log.smethod_1("PushNotify", "cannot set enable without changed， enable =  " + enable);
				return;
			}
			ConfigMgr.setInt("nSwitchPushNotify", (int)enable);
			if (enable == PushNotifySwitch.PushDisable)
			{
				Log.smethod_4("PushNotify", " cmd to disable push notify. ");
				this.doClosePushChannel();
				return;
			}
			Log.smethod_4("PushNotify", " cmd to enable push notify. ");
			this.checkOpenPushChannel();
			this.checkNeedRegisterChannel();
		}
		public bool isEnable()
		{
			return 1 != ConfigMgr.getInt("nSwitchPushNotify", 1);
		}
		private void updateChannel()
		{
			if (!AccountMgr.hasValidAccount())
			{
				Log.smethod_1("PushNotify", "cannot update channel without valid account. ");
				return;
			}
			if (1 == ConfigMgr.getInt("nSwitchPushNotify", 1))
			{
				Log.smethod_4("PushNotify", "cannot update channel without enabled push settings. ");
				return;
			}
			this.doClosePushChannel();
			this.checkOpenPushChannel();
			this.checkNeedRegisterChannel();
		}
		public void doClosePushChannel()
		{
			if (this.mPushChannel == null)
			{
				Log.smethod_1("PushNotify", "cannot close push channel without open.");
				return;
			}
			Log.smethod_4("PushNotify", "push channel closed, name = " + this.mChannelName);
			try
			{
				this.mPushChannel.Close();
				this.mPushChannel.Dispose();
			}
			catch (Exception ex)
			{
				Log.smethod_1("PushNotify", ex.get_Message());
			}
			this.mPushChannel = null;
		}
		public void closePushChannel()
		{
			this.doClosePushChannel();
			PushNotifyMgr.cleanPushSetting();
		}
		public static void cleanPushSetting()
		{
			GConfigMgr.delete<PushChannelSettings>();
		}
		private void onWatcherHandler(EventWatcher watcher, BaseEventArgs evtArgs)
		{
			if (evtArgs.mEventID == EventConst.ON_NETSCENE_AUTH_SUCCESS)
			{
				this.checkOpenPushChannel();
				this.checkNeedRegisterChannel();
				return;
			}
			if (evtArgs.mEventID == EventConst.ON_NET_LONGCONN_KEEPALIVE)
			{
				this.checkPushChannelConnectStatus();
			}
		}
		public void printfInfo()
		{
			PushChannelSettings pushChannelSettings = GConfigMgr.smethod_0<PushChannelSettings>();
			Log.smethod_5("PushNotify", "setting push channel uri = " + pushChannelSettings.strPushChannelUri);
			Log.smethod_5("PushNotify", "setting push channel user = " + pushChannelSettings.strPushUsrName);
			Log.smethod_5("PushNotify", "setting push channel registered = " + pushChannelSettings.strRegChannelUri);
			if (this.mPushChannel != null)
			{
				Log.smethod_5("PushNotify", "current channel name = " + this.mPushChannel.get_ChannelName());
				Log.smethod_5("PushNotify", "current channel status = " + this.getCurrentConnStatus());
				Log.smethod_5("PushNotify", "current channel uri = " + this.mPushChannel.get_ChannelUri());
			}
		}
		private bool isAccountEnablePush()
		{
			return AccountMgr.hasValidAccount() && ConfigMgr.getInt("nSwitchPushNotify", 1) != 1;
		}
		private ChannelConnectionStatus getCurrentConnStatus()
		{
			ChannelConnectionStatus result;
			try
			{
				result = this.mPushChannel.get_ConnectionStatus();
			}
			catch (Exception ex)
			{
				Log.smethod_1("PushNotify", ex.get_Message());
				result = 1;
			}
			return result;
		}
		public void checkPushChannelConnectStatus()
		{
			if (this.mPushChannel == null)
			{
				return;
			}
			if (this.getCurrentConnStatus() == null)
			{
				this.checkNeedRegisterChannel();
				return;
			}
			Log.smethod_4("PushNotify", " push channel disconnect, prepare to update channel ... ");
			this.updateChannel();
		}
		private void checkOpenPushChannel()
		{
			if (this.mPushChannel != null)
			{
				Log.smethod_1("PushNotify", "push channel open already, may be not closed. ");
				return;
			}
			if (!this.isAccountEnablePush())
			{
				Log.smethod_1("PushNotify", "cannot open push channel without valid account or push disabled. ");
				return;
			}
			PushChannelSettings pushChannelSettings = GConfigMgr.smethod_0<PushChannelSettings>();
			if (pushChannelSettings.strPushUsrName != null && pushChannelSettings.strPushUsrName.get_Length() > 0)
			{
				string text = "MicroMsgPushChannel" + pushChannelSettings.strPushUsrName;
				HttpNotificationChannel httpNotificationChannel = HttpNotificationChannel.Find(text);
				if (httpNotificationChannel != null)
				{
					Log.smethod_4("PushNotify", "old push channel closed for open new channel, name = " + text);
					httpNotificationChannel.Close();
					httpNotificationChannel.Dispose();
					PushNotifyMgr.cleanPushSetting();
				}
			}
			this.mChannelName = "MMPC" + AppInfoHelper.ProductId.GetHashCode();
			if (!this.doOpenPushChannel())
			{
				this.closePushChannel();
				this.doOpenPushChannel();
			}
		}
		private bool doOpenPushChannel()
		{
			try
			{
				this.mPushChannel = HttpNotificationChannel.Find(this.mChannelName);
				if (this.mPushChannel == null)
				{
					this.mPushChannel = new HttpNotificationChannel(this.mChannelName);
					this.mPushChannel.add_ChannelUriUpdated(new EventHandler<NotificationChannelUriEventArgs>(this.onPushChannelUriUpdated));
					this.mPushChannel.add_ErrorOccurred(new EventHandler<NotificationChannelErrorEventArgs>(this.onPushChannelErrorOccurred));
					this.mPushChannel.Open();
					this.mPushChannel.BindToShellToast();
					this.mPushChannel.BindToShellTile();
					if (this.mPushChannel.get_ChannelUri() != null)
					{
						Log.smethod_4("PushNotify", "create push channel completed, uri = " + this.mPushChannel.get_ChannelUri().ToString());
						this.checkNeedSaveChannel(this.mPushChannel.get_ChannelUri().ToString());
					}
					else
					{
						Log.smethod_4("PushNotify", "create push channel success, wait event on_update_uri. ");
					}
				}
				else
				{
					this.mPushChannel.add_ChannelUriUpdated(new EventHandler<NotificationChannelUriEventArgs>(this.onPushChannelUriUpdated));
					this.mPushChannel.add_ErrorOccurred(new EventHandler<NotificationChannelErrorEventArgs>(this.onPushChannelErrorOccurred));
					if (!(this.mPushChannel.get_ChannelUri() != null))
					{
						Log.smethod_1("PushNotify", "open push channel completed without uri, need to close and recreate channel.. ");
						bool result = false;
						return result;
					}
					Log.smethod_4("PushNotify", "open push channel success , status = " + this.getCurrentConnStatus());
					this.checkNeedSaveChannel(this.mPushChannel.get_ChannelUri().ToString());
				}
			}
			catch (Exception ex)
			{
				Log.smethod_1("PushNotify", "open push channel failed , may be need to restart mobile.");
				Log.smethod_1("PushNotify", ex.get_Message());
				bool result = false;
				return result;
			}
			return true;
		}
		private void onPushChannelUriUpdated(object sender, NotificationChannelUriEventArgs e)
		{
			string string_0 = e.get_ChannelUri().ToString();
			Log.smethod_4("PushNotify", "push channel uri updated. uri =  " + string_0);
			if (this.isOpenChannelFromSync)
			{
				if (this.checkNeedSaveChannel(string_0))
				{
					this.checkNeedRegisterChannel();
				}
				return;
			}
			Deployment.get_Current().get_Dispatcher().BeginInvoke(delegate
			{
				if (this.checkNeedSaveChannel(string_0))
				{
					this.checkNeedRegisterChannel();
				}
			});
		}
		private bool checkNeedSaveChannel(string string_0)
		{
			if (string_0 == null || string_0.get_Length() <= 0)
			{
				Log.smethod_1("PushNotify", "save channel with invalid uri. ");
				return false;
			}
			this.gotChannelUrl = true;
			PushChannelSettings pushChannelSettings = GConfigMgr.smethod_0<PushChannelSettings>();
			if (string_0.Equals(pushChannelSettings.strPushChannelUri))
			{
				Log.smethod_4("PushNotify", "same push channel uri ,no need to save. ");
				return false;
			}
			pushChannelSettings.strPushChannelUri = string_0;
			Log.smethod_4("PushNotify", "save new push channel ,uri =  " + string_0);
			GConfigMgr.save<PushChannelSettings>(true);
			return true;
		}
		private void checkNeedRegisterChannel()
		{
			if (!this.isAccountEnablePush())
			{
				Log.smethod_4("PushNotify", "cannot register channel without valid account, try later. ");
				return;
			}
			PushChannelSettings pushChannelSettings = GConfigMgr.smethod_0<PushChannelSettings>();
			if (pushChannelSettings.strPushChannelUri == null || pushChannelSettings.strPushChannelUri.get_Length() <= 0)
			{
				Log.smethod_4("PushNotify", "cannot register channel without valid uri, try later. ");
				return;
			}
			if (pushChannelSettings.strPushChannelUri.Equals(pushChannelSettings.strRegChannelUri) && AccountMgr.getCurAccount().strUsrName.Equals(pushChannelSettings.strPushUsrName))
			{
				this.regCompleted = true;
				this.waitPushEvent.Set();
				Log.smethod_4("PushNotify", "no need to register channel without changes. ");
				return;
			}
			ServiceCenter.scenePushChannelReg.doScene(pushChannelSettings.strPushChannelUri);
		}
		private void onPushChannelErrorOccurred(object sender, NotificationChannelErrorEventArgs e)
		{
			Log.smethod_1("PushNotify", string.Format("A push notification {0} error occurred.  {1} ({2})", e.get_ErrorType(), e.get_Message(), e.get_ErrorCode()));
			if (e.get_ErrorType() == 1)
			{
				this.closePushChannel();
			}
		}
		private void onPushChannelShellToastNotificationReceived(object sender, NotificationEventArgs e)
		{
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.AppendFormat("Received Toast {0}:\n", new object[]
			{
				DateTime.get_Now().ToShortTimeString()
			});
			using (IEnumerator<string> enumerator = e.get_Collection().get_Keys().GetEnumerator())
			{
				while (enumerator.MoveNext())
				{
					string current = enumerator.get_Current();
					stringBuilder.AppendFormat("{0}: {1}\n", new object[]
					{
						current,
						e.get_Collection().get_Item(current)
					});
					if (string.Compare(current, "wp:Param", CultureInfo.get_InvariantCulture(), 1) == 0)
					{
						string arg_94_0 = e.get_Collection().get_Item(current);
					}
				}
			}
			Log.smethod_4("PushNotify", "received toast notify, message =  " + stringBuilder.ToString());
			EventCenter.postEvent(EventConst.ON_PUSH_TOAST_RECEIVED, stringBuilder.ToString(), null);
		}
	}
}
